<template>
  <div>
    <EleGallery
      v-if="uploadDisabled"
      :lazy="state.lazy"
      :remove-fn="remove"
      :size="state.size"
      :source="state.pdfFileList"
      :title="title"
    />
    <EleGallery
      v-else
      :lazy="state.lazy"
      :size="state.size"
      :source="state.pdfFileList"
      :title="title"
    />
    <div class="uploadVideo-flex">
      <div v-for="(item, index) in state.fileList" :key="index">
        <div
          v-if="item.type === 'video'"
          style="width: 100%; padding-right: 10px"
        >
          <audio
            id="audio"
            :style="{
              width: '250px',
            }"
            controls="controls"
          >
            <source :src="item.url" type="audio/aac" />
            您的浏览器不支持音频播放
          </audio>
          <el-icon v-if="uploadDisabled" class="del-icon">
            <Delete @click="remove(index, item)" />
          </el-icon>
        </div>
        <div
          v-if="item.type === 'img'"
          style="width: 100%; padding-right: 10px"
        >
          <el-image
            :style="{
              width: state.size + 'px',
              height: state.size + 'px',
              lineHeight: state.size + 'px',
            }"
            :src="item.url"
            :preview-src-list="state.imgFileList"
            :preview-teleported="true"
          >
          </el-image>
          <el-icon v-if="uploadDisabled" class="del-icon">
            <Delete @click="remove(index, item)" />
          </el-icon>
        </div>
        <div
          v-if="item.type === 'other'"
          style="width: 100%; padding-right: 10px"
        >
          <p class="download-a" @click="clickLink($event, item)">
            {{ item.name }}
          </p>
          <i
            class="el-icon-delete"
            v-if="uploadDisabled"
            @click="remove(index, item)"
          ></i>
          <!-- <p
            class="remove-download"
            v-if="uploadDisabled"
            @click="remove(index)"
          >
            ×
          </p> -->
        </div>
      </div>
    </div>

    <el-upload
      v-if="uploadDisabled"
      :action="action"
      :headers="state.myHeaders"
      :limit="limit"
      :show-file-list="listType === 'text' && showFileList ? true : false"
      :list-type="listType"
      :on-success="handleVideoSuccess"
      :on-error="handleVideoError"
      :before-upload="beforeUpload"
      :on-progress="uploadVideoProcess"
      :on-preview="handlePictureCardPreview"
      :on-exceed="handleExceed"
      :file-list="state.fileListName"
      :on-remove="onRemove"
    >
      <div
        v-if="state.videoFlag == false && listType === 'picture-card'"
        :style="{
          width: state.size + 'px',
          height: state.size + 'px',
          lineHeight: state.size + 'px',
          textAlign: 'center',
        }"
      >
        <el-icon><Plus /></el-icon>
      </div>
      <div v-else-if="uploadDisabled && listType === 'text'" class="up-btn">
        <el-button>点击上传</el-button>
      </div>

      <!-- <el-progress
        v-if="videoFlag == true"
        type="circle"
        :percentage="videoUploadPercent"
        style="margin-top: 30px"
      ></el-progress> -->
    </el-upload>
    <p v-if="uploadDisabled">
      请上传<span>{{ fileType.join('/') }}</span
      >格式文件且为文件白名单支持的格式，且大小不超过<span>{{ fileSize }}</span
      >Mb
    </p>
  </div>
</template>

<script setup name="UploadVideo">
import axios from 'axios'
import EleGallery from '../UploadImg/eleGallery'
import { mapState } from 'vuex'

const { proxy } = getCurrentInstance()
const emit = defineEmits()
const props = defineProps({
  // 上传地址
  action: {
    type: String,
    // required: true,
  },
  //文件大小
  fileSize: {
    type: Number,
    default: 10,
  },
  //回显文件数据
  fileData: {
    type: Array,
    default() {
      return []
    },
  },
  //组件可编辑性
  uploadDisabled: {
    type: Boolean,
    default: true,
  },
  // 支持上传的文件类型
  fileType: {
    type: Array,
    default() {
      return ['png', 'jpg', 'jpeg', 'mp3', 'aac']
    },
  },
  limit: {
    type: Number,
    default: 5,
  },
  listType: {
    type: String,
    default: 'text',
  },
  showFileList: {
    type: Boolean,
    default: false,
  },
})
const state = reactive({
  myHeaders: {
    Authorization: '',
  },
  size: 150, //高宽
  videoFlag: false,
  videoUploadPercent: 0, //视频上传进度
  imgFileList: [], //图片文件列表
  pdfFileList: [],
  fileList: [], //文件列表
  urlList: [], //地址列表
  fileListName: [],
  lazy: true,
  audioDuration: null,
})

const token = computed(() => {
  return proxy.$store.state.user.token
})

watch(
  () => state.fileList,
  (val) => {
    state.imgFileList = []
    state.pdfFileList = []
    if (val.length) {
      val.forEach((item) => {
        if (item.type === 'img') {
          state.imgFileList.push(item.url)
        }
        if (item.type === 'pdf') {
          state.pdfFileList.push(item.url)
        }
      })
    }
  }
)

watch(
  () => props.fileData,
  (val) => {
    if (val.length) {
      state.fileList = val.map((item, index) => {
        let imgType = ['png', 'jpg', 'jpeg', 'gif']
        let videoType = ['mp3', 'm4a', 'aac', 'wav', 'audio', 'x-m4a']
        let wordType = ['docx', 'doc', 'xls', 'xlsx']
        let type = item.filePath.split('.')[1]
        let name = item.name
        if (imgType.indexOf(type) > -1) {
          item = {
            ...item,
            type: 'img',
            name: name,
            url: axios.defaults.baseURL + '/pub' + item.filePath,
            filePath: item.filePath,
          }
        } else if (videoType.indexOf(type) > -1) {
          item = {
            ...item,
            type: 'video',
            name: name,
            url: axios.defaults.baseURL + '/pub' + item.filePath,
            filePath: item.filePath,
          }
        } else if (wordType.indexOf(type) > -1) {
          item = {
            ...item,
            type: 'other',
            name: name,
            url: '/pub' + item.filePath,
          }
        } else if (['pdf'].indexOf(type) > -1) {
          item = {
            ...item,
            type: 'pdf',
            name: name,
            url: item.filePath,
          }
        }
        return item
      })
      state.fileListName = val.map((item) => {
        let obj = {
          ...item,
          name: item.name,
          url: axios.defaults.baseURL + '/pub' + item.filePath,
        }
        return obj
      })
    } else {
      state.fileList = []
      state.fileListName = []
    }
  },
  {
    immediate: true,
    deep: true,
  }
)

onMounted(() => {
  state.myHeaders.Authorization = token
})

const clickLink = (e, file) => {
  if (file) {
    axios({ method: 'get', url: file.url, responseType: 'blob' }).then(
      (res) => {
        let blob = res
        let urlL = window.URL.createObjectURL(new Blob([blob]))
        let link = document.createElement('a')
        link.href = urlL
        link.download = file.name
        link.click()
      }
    )
  }
}

const handleExceed = (files, fileList) => {
  proxy.$message.warning(` 只能上传 ${props.limit} 个文件`)
}
const onRemove = (file, fileList) => {
  emit('upload', fileList)
}
//删除
const remove = (index, item = undefined) => {
  if (item && item.name) {
    state.fileList.splice(index, 1)
  } else {
    state.fileList = state.fileList.filter((row) => {
      if (state.pdfFileList[index] !== row.url) {
        return row
      }
    })
  }
  emit('upload', state.fileList)
}

const handlePictureCardPreview = (file) => {
  if (file) {
    let url = file.url.split('/api')
    axios({ method: 'get', url: url[1], responseType: 'blob' }).then((res) => {
      let blob = res
      let urlL = window.URL.createObjectURL(new Blob([blob]))
      let link = document.createElement('a')
      link.href = urlL
      link.download = file.name
      link.click()
    })
  }
}
//验证文件格式和文件大小
const beforeUpload = (file) => {
  const fileType = file.type.split('/')[0]
  if (fileType === 'audio') {
    getTimes(file)
  }

  //验证文件格式
  let fileTypeArr = file.name.split('.')[file.name.split('.').length - 1]

  if (props.fileType.indexOf(fileTypeArr) === -1) {
    proxy.$message.error(
      `文件格式不正确, 请上传 ${props.fileType.join(' / ')} 格式文件!`
    )
    return false
  }

  let file_type_list = proxy.$store.state.permission.dict['file_type_list']
  if (file_type_list && file_type_list.length) {
    let uploadType = file.name.split('.')[file.name.split('.').length - 1]
    let file_type_list_arr = []
    file_type_list.forEach((item) => {
      file_type_list_arr.push(item.code)
    })
    if (!String(file_type_list_arr).includes(uploadType)) {
      proxy.$message.error({
        message: `文件格式【${uploadType}】非白名单文件类型格式，不支持上传`,
        showClose: true,
        duration: 3500,
      })
      return false
    }
  }

  //验证文件大小
  const maxFileSize = file.size / 1024 / 1024 < props.fileSize
  if (!maxFileSize) {
    proxy.$message.error(`上传文件大小不能超过${props.fileSize}Mb！`)
    return false
  }
}
//上传进度显示
const uploadVideoProcess = (event, file, fileList) => {
  state.videoFlag = true
  state.videoUploadPercent = file.percent
}
const getTimes = (file) => {
  //获取录音时长
  let url = URL.createObjectURL(file)
  let audioElement = new Audio(url)
  audioElement.addEventListener('loadedmetadata', (_event) => {
    state.audioDuration = audioElement.duration
  })
}
//上传成功
const handleVideoSuccess = (res, file, fileList) => {
  state.videoFlag = false
  state.videoUploadPercent = 0
  if (res.success) {
    const fileType = file.raw.type.split('/')[0]
    file.filePath = res.data[0]
    if (fileType === 'video' || fileType === 'audio') {
      file.type = 'video'
      file.audioDuration = state.audioDuration
    } else if (fileType === 'image') {
      file.type = 'img'
    } else if (fileType === 'pdf') {
      file.type = 'pdf'
    } else {
      file.type = 'other'
    }
    if (props.listType === 'text') {
      let obj = {
        name: file.name,
        url: file.filePath,
      }
      state.fileListName.push(obj)
    }
    emit('upload', fileList)
  } else {
    proxy.$message.error('文件上传失败，请重新上传！')
  }
}
//上传失败
const handleVideoError = (err, file, fileList) => {
  state.videoFlag = false
  state.videoUploadPercent = 0
  proxy.$message.error('文件上传失败，请重新上传！')
}
</script>

<style scoped>
.uploadVideo-flex {
  display: flex;
}
.del-icon {
  width: 20px;
  height: 20px;
  line-height: 20px;
  border-bottom-left-radius: 15px;
  text-align: center;
  display: inline-block;
  background-color: #7f7f7f;
  color: #ffffff;
  background-size: 18px;
  background-repeat: no-repeat;
  background-position: 50%;
  position: relative;
  top: -136px;
  left: -23px;
  cursor: pointer;
}
.bgimg {
  border: 1px dashed #d9d9d9;
  border-radius: 4px;
  background-color: #ebeef5;
  background-image: url(../../assets/image/no-img.png);
  background-repeat: no-repeat;
  background-size: 40px 40px;
  background-position: 50% 50%;
}
.up-btn {
  display: flex;
  align-items: center;
}
.el-upload__tip {
  padding-left: 10px;
}
.download-a {
  display: inline-block;
  color: #6dc1a9;
}
.download-a:hover {
  text-decoration: underline;
  color: #6dc1a9;
} /* 鼠标在链接上 */
.remove-download {
  display: inline-block;
  color: #7f7f7f;
  cursor: default;
}
</style>
